package com.infore.siteManagement.service.equipment.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.infore.siteManagement.constant.Constants;
import com.infore.siteManagement.constant.ResultConstants;
import com.infore.siteManagement.dto.EquipmentSampleAddDto;
import com.infore.siteManagement.entity.SiteBasicFile;
import com.infore.siteManagement.entity.equipment.EquipSampleAndProject;
import com.infore.siteManagement.entity.equipment.EquipmentModel;
import com.infore.siteManagement.entity.equipment.EquipmentSample;
import com.infore.siteManagement.enums.ResultStatus;
import com.infore.siteManagement.repository.ISiteBasicFileRepository;
import com.infore.siteManagement.repository.equipment.IEquipSampleAndProjectRepository;
import com.infore.siteManagement.repository.equipment.IEquipSampleRepository;
import com.infore.siteManagement.select.QueryDispatcher;
import com.infore.siteManagement.select.dto.QueryParamDto;
import com.infore.siteManagement.select.util.PageObject;
import com.infore.siteManagement.select.util.QueryUtil;
import com.infore.siteManagement.service.IFileService;
import com.infore.siteManagement.service.equipment.IEquipSampleService;
import com.infore.siteManagement.util.ArrayUtils;
import com.infore.siteManagement.util.FileUtil;
import com.infore.siteManagement.util.ObjectMapperUtil;
import com.infore.siteManagement.util.Page;
import com.infore.siteManagement.util.PageUtil;
import com.infore.siteManagement.util.ResultEntity;
import com.infore.siteManagement.util.UUIDGenerator;
import com.infore.siteManagement.vo.EquipmentSampleVo;

@Service
public class EquipSampleServiceImpl implements IEquipSampleService {

	@Autowired
	private IEquipSampleRepository iEquipSampleRepository;
	@Autowired
	private QueryDispatcher queryDispatcher;
	@Autowired
	private ObjectMapperUtil objectMapperUtil;
	@Autowired
	private IEquipSampleAndProjectRepository iEquipSampleAndProjectRepository;
	@Autowired
	private ISiteBasicFileRepository iSiteBasicFileRepository;
	@Autowired
	private IFileService iFileService;

	public ResultEntity query(QueryParamDto queryParamDto) {
		if (org.springframework.util.StringUtils.isEmpty(queryParamDto)) {// 无任何条件查询
			List<EquipmentSample> list = iEquipSampleRepository.findAll();
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
			// 仅分页查询
		} else if (!org.springframework.util.StringUtils.isEmpty(queryParamDto.getPageObject())
				&& org.springframework.util.StringUtils.isEmpty(queryParamDto.getQueryCondition())
				&& org.springframework.util.StringUtils.isEmpty(queryParamDto.getAssembleCondition())
				&& org.springframework.util.StringUtils.isEmpty(queryParamDto.getAssembleSql())) {
			org.springframework.data.domain.Page<EquipmentSample> pageable = iEquipSampleRepository
					.findAll(queryParamDto.getPageObject().getPageRequest());
			Page<EquipmentSample> page = PageUtil.pageConvert(pageable);
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(page);
			// 只传属性不传字段的查询
		} else if (org.apache.commons.lang.StringUtils.isBlank(queryParamDto.getAssembleSql().getSelect())) {
			return this.queryAll(queryParamDto);
		}
		// 指定字段查询
		return queryDispatcher.dispatcher(queryParamDto, EquipmentSample.class);
	}

	@SuppressWarnings("serial")
	public ResultEntity queryAll(QueryParamDto queryParamDto) {
		// 判断是否有条件再判断是否需要分页,不分页必须传null
		if (!org.springframework.util.StringUtils.isEmpty(queryParamDto.getPageObject())) {
			// 需要分页
			org.springframework.data.domain.Page<EquipmentSample> pageAble = iEquipSampleRepository
					.findAll(new Specification<EquipmentSample>() {
						public Predicate toPredicate(Root<EquipmentSample> root, CriteriaQuery<?> query,
								CriteriaBuilder criteriaBuilder) {
							// 构建条件
							List<Predicate> predicates = com.infore.siteManagement.select.util.QueryUtil
									.createQueryCondition(queryParamDto, criteriaBuilder, root);
							// 组装条件
							Predicate predicate = com.infore.siteManagement.select.util.QueryUtil
									.assembleCondition(queryParamDto, criteriaBuilder, predicates);
							QueryUtil.assembleSql(queryParamDto, criteriaBuilder, query, root, predicate);
							return query.getRestriction();
						}
					}, queryParamDto.getPageObject().getPageRequest());
			Page<EquipmentSample> page = PageUtil.pageConvert(pageAble);
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(page);
		} else {
			List<EquipmentSample> list = iEquipSampleRepository.findAll(new Specification<EquipmentSample>() {
				public Predicate toPredicate(Root<EquipmentSample> root, CriteriaQuery<?> query,
						CriteriaBuilder criteriaBuilder) {
					// 构建条件
					List<Predicate> predicates = com.infore.siteManagement.select.util.QueryUtil
							.createQueryCondition(queryParamDto, criteriaBuilder, root);
					// 组装条件
					Predicate predicate = com.infore.siteManagement.select.util.QueryUtil
							.assembleCondition(queryParamDto, criteriaBuilder, predicates);
					QueryUtil.assembleSql(queryParamDto, criteriaBuilder, query, root, predicate);
					return query.getRestriction();
				}
			});
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
		}
	}

	public ResultEntity delete(String id) {
		List<String> ids = ArrayUtils.stringToList(id);
		List<EquipmentSample> equipmentSamples = iEquipSampleRepository.findByIdIn(ids);
		for (EquipmentSample equipmentSample : equipmentSamples) {
			Set<SiteBasicFile> siteBasicFiles = equipmentSample.getQrCodes();
			if (siteBasicFiles != null && siteBasicFiles.size() > 0) {
				siteBasicFiles.forEach(f -> {
					String path = f.getFilePath();
					File file = new File(FileUtil.BASE_PATH + path);
					file.delete();
				});
			}
		}
		try {
			iEquipSampleRepository.deleteAll(equipmentSamples);
		} catch (Exception e) {
			e.printStackTrace();
			return new ResultEntity(ResultStatus.SUCCESS,Constants.DELETE_FAILUE);
		}
		return new ResultEntity(ResultStatus.SUCCESS,Constants.DELETE_SUCCESS);
	}

	public ResultEntity edit(EquipmentSampleAddDto equipmentSampleAddDto, MultipartFile[] imageFiles) {
		Boolean falg = false;// 判断是编辑还是新增，默认新增
		try {
			String id = equipmentSampleAddDto.getId();
			// 如果id为空则set一个uuid，编辑时JPA的update会自动删除中间表
			if (StringUtils.isBlank(id)) {
				id = UUIDGenerator.getUUID();
			} else {
				EquipmentSample equipmentSample = iEquipSampleRepository.findById(id).orElse(null);
				if (equipmentSample == null) {
					return new ResultEntity(ResultStatus.SUCCESS, ResultConstants.NO_SUCH_OBJECT);
				}
				falg = true;
			}
			String equipmentModelId = equipmentSampleAddDto.getEquipmentModelId();
			String factoryCode = equipmentSampleAddDto.getFactoryCode();
			Date installDate = equipmentSampleAddDto.getInstallDate();
			String isEnable = equipmentSampleAddDto.getIsEnable();
			Date producedDate = equipmentSampleAddDto.getProducedDate();
			String stationMn = equipmentSampleAddDto.getStationMn();
			String equipModel = equipmentSampleAddDto.getEquipModel();
			List<String> projectCode = equipmentSampleAddDto.getProjectCode();
			// 处理仪器实例表
			EquipmentSample equipmentSample = new EquipmentSample();
			equipmentSample.setEquipmentModelId(equipmentModelId);
			equipmentSample.setFactoryCode(factoryCode);
			equipmentSample.setId(id);
			equipmentSample.setInstallDate(installDate);
			equipmentSample.setIsEnable(isEnable);
			equipmentSample.setProducedDate(producedDate);
			equipmentSample.setStationMn(stationMn);
			equipmentSample.setEquipModel(equipModel);
			iEquipSampleRepository.save(equipmentSample);
			// 处理中间表
			List<EquipSampleAndProject> list = new ArrayList<EquipSampleAndProject>();
			for (String code : projectCode) {
				EquipSampleAndProject equipSampleAndProject = new EquipSampleAndProject();
				equipSampleAndProject.setEquipSampleId(id);
				equipSampleAndProject.setProjectCode(code);
				list.add(equipSampleAndProject);
			}
			iEquipSampleAndProjectRepository.saveAll(list);
			// 处理文件
			ResultEntity resultEntity = iFileService.uploadSingle(FileUtil.EQUIP_SAMPL_IMAGE_FILE, imageFiles);
			List<SiteBasicFile> image = objectMapperUtil.convertList(resultEntity, SiteBasicFile.class);
			if (image != null && image.size() > 0) {
				for (SiteBasicFile siteBasicFile : image) {
					siteBasicFile.setEquipSampleQrcode(id);
				}
			}
			iSiteBasicFileRepository.saveAll(image);
		} catch (Exception e) {
			e.printStackTrace();
			return new ResultEntity(ResultStatus.SUCCESS, Constants.DEAL_FAILUE);
		}
		if (falg) {
			return new ResultEntity(ResultStatus.SUCCESS, Constants.UPDATE_SUCCESS);
		} else {
			return new ResultEntity(ResultStatus.SUCCESS, Constants.INSERT_SUCCESS);
		}
	}

	public ResultEntity querySingleByStation(String stationId,String mn, PageObject pageObject) {
		List<EquipmentSample> equipmentSamples = new ArrayList<EquipmentSample>();
		if (StringUtils.isNotBlank(stationId) && StringUtils.isBlank(mn)) {
			equipmentSamples = iEquipSampleRepository.findByStationStationId(stationId);
		}else if (StringUtils.isNotBlank(mn) && StringUtils.isBlank(stationId)) {
			equipmentSamples = iEquipSampleRepository.findByStationMn(mn);
		}
		//List<EquipmentSample> equipmentSamples = iEquipSampleRepository.findByStationMn(mn);
		List<EquipmentSampleVo> list = new ArrayList<EquipmentSampleVo>();
		for (EquipmentSample equipmentSample : equipmentSamples) {
			EquipmentModel equipmentModel = equipmentSample.getEquipmentModel();// 得到仪器实例的仪器模板
			String projectNames;// 仪器关联因子的名称
			List<String> projectList = equipmentSample.getProjects().stream().map(m -> m.getProjectName())
					.collect(Collectors.toList());
			projectNames = StringUtils.join(projectList, ",");
			List<String> qrCode = new ArrayList<String>();// 仪器二维码图片链接
			Set<SiteBasicFile> image = equipmentSample.getQrCodes();
			qrCode = image.stream().map(m -> m.getFilePath()).collect(Collectors.toList());
			String reagent = "";// 试剂
			List<String> reagentName = equipmentModel.getEquipAndReagents().stream()
					.map(m -> m.getEquipReagent().getReagentName()).collect(Collectors.toList());
			if (reagentName != null && reagentName.size() > 0) {
				reagent = StringUtils.join(reagentName, ",");
			}
			// 封装vo
			String equipName = equipmentModel.getEquipmentName();
			String woocu = equipmentModel.getWoocu();
			String analysisMethod = equipmentModel.getAnalysisMethod();
			String detectionLimit = equipmentModel.getDetectionLimit();
			String upperLimit = equipmentModel.getUpperLimit() == null ? "" : equipmentModel.getUpperLimit();
			String lowerLimit = equipmentModel.getLowerLimit() == null ? "" : equipmentModel.getLowerLimit();
			String factoryCode = equipmentSample.getFactoryCode();
			Date installDate = equipmentSample.getInstallDate();
			String isEnable = equipmentSample.getIsEnable();
			Date producedDate = equipmentSample.getProducedDate();
			EquipmentSampleVo vo = new EquipmentSampleVo();
			vo.setAnalysisMethod(analysisMethod);
			vo.setDetectionLimit(detectionLimit);
			vo.setEquipName(equipName);
			vo.setFactoryCode(factoryCode);
			vo.setInstallDate(installDate);
			vo.setIsEnable(isEnable);
			vo.setLowerLimit(lowerLimit);
			vo.setProducedDate(producedDate);
			vo.setProjectNames(projectNames);
			vo.setQeCode(qrCode);
			vo.setReagent(reagent);
			vo.setUpperLimit(upperLimit);
			vo.setWoocu(woocu);
			list.add(vo);
		}
		// 判断分页
		if (pageObject != null && pageObject.getPageSize() != null && pageObject.getPageNumber() != null) {
			Page<EquipmentSampleVo> page = PageUtil.inventedObjectPage(list, pageObject);
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(page);
		}
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(list);
	}

}
